package com.lechi.web.job;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.lechi.web.common.utils.DateUtils;
import com.lechi.web.common.utils.StringUtils;
import com.lechi.web.common.utils.spring.SpringUtils;
import com.lechi.web.constants.Constants;
import com.lechi.web.framework.util.GuavaCacheUtil;
import com.lechi.web.record.FTPConfig;
import com.lechi.web.system.domain.IotInterfaceApiBo;
import com.lechi.web.system.domain.IotMonitorDataBo;
import com.lechi.web.system.service.IIotInterfaceApiService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.net.ftp.FTPClient;
import org.quartz.Job;
import org.quartz.JobExecutionContext;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;

/**
 * The type Get sensor data job.
 *
 * @author yangguang
 */
@Slf4j
public class UploadSensorDataJob implements Job {

    public static final Map<String, String> map = new ConcurrentHashMap<>();

    public static final Map<String, List<Long>> sensorsMap = new ConcurrentHashMap<>();

    static {
        map.put("LC001_1584", "150厘米空气温度");
        map.put("LC001_1585", "150厘米空气湿度");
        map.put("LC001_1586", "40厘米空气温度");
        map.put("LC001_1587", "40厘米空气湿度");
        map.put("LC001_1588", "10厘米空气温度");
        map.put("LC001_1589", "10厘米空气湿度");
        map.put("LC001_1596", "翻斗雨量");
        map.put("LC001_1601", "土壤氧化还原");
        map.put("LC001_1610", "有效光量密度");
        map.put("LC001_1616", "通量密度与照度转换");

        map.put("LC002_1527", "150厘米空气温度");
        map.put("LC002_1528", "150厘米空气湿度");
        map.put("LC002_1529", "40厘米空气温度");
        map.put("LC002_1530", "40厘米空气湿度");
        map.put("LC002_1531", "10厘米空气温度");
        map.put("LC002_1532", "10厘米空气湿度");
        map.put("LC002_1539", "翻斗雨量");
        map.put("LC002_1544", "土壤氧化还原");
        map.put("LC002_1553", "有效光量密度");
        map.put("LC002_1559", "通量密度与照度转换");

        // LC001   1 分钟
        sensorsMap.put("LC001_1min", List.of(1581L, 1582L, 1583L, 1584L, 1585L, 1586L, 1587L, 1588L, 1589L, 1590L, 1591L, 1592L, 1593L, 1594L, 1595L, 1596L, 1602L));
        // LC001   10 分钟
        sensorsMap.put("LC001_10min", List.of(1597L, 1606L, 1607L, 1608L, 1609L, 1610L, 1611L, 1612L, 1613L, 1614L, 1615L, 1616L, 1617L, 1618L));
        // LC001   60 分钟
        sensorsMap.put("LC001_60min", List.of(1599L, 1600L, 1601L, 1603L, 1604L, 1605L, 1619L, 1620L, 1621L, 1622L, 1623L, 1624L, 1625L, 1626L, 1627L, 1628L, 1629L, 1630L));
        // 24 小时
        sensorsMap.put("LC001_24hour", List.of(1598L));

        // LC002   1 分钟
        sensorsMap.put("LC002_1min", List.of(1524L, 1525L, 1526L, 1527L, 1528L, 1529L, 1530L, 1531L, 1532L, 1533L, 1534L, 1535L, 1536L, 1537L, 1538L, 1539L, 1545L));
        // LC002   10 分钟
        sensorsMap.put("LC002_10min", List.of(1540L, 1549L, 1550L, 1551L, 1552L, 1553L, 1554L, 1555L, 1556L, 1557L, 1558L, 1559L, 1560L, 1561L));
        // LC002   60 分钟
        sensorsMap.put("LC002_60min", List.of(1542L, 1543L, 1544L, 1546L, 1547L, 1548L, 1563L, 1575L, 1576L, 1565L, 1577L, 1567L, 1578L, 1569L, 1579L, 1571L, 1580L, 1573L));
        // 24 小时
        sensorsMap.put("LC002_24hour", List.of(1541L));
    }

    @Override
    public void execute(JobExecutionContext context) {
        final String cron = context.getMergedJobDataMap().get("cron") + "";
        IotInterfaceApiBo iotInterfaceApiBo = new IotInterfaceApiBo();
        iotInterfaceApiBo.setId(2L);
        List<IotInterfaceApiBo> list = SpringUtils.getBean(IIotInterfaceApiService.class).selectAuthInterfaceDevice(iotInterfaceApiBo);
        for (IotInterfaceApiBo interfaceApiBo : list) {
            upload(interfaceApiBo, cron);
        }
    }

    public void upload(IotInterfaceApiBo interfaceApiBo, String cron) {
        // 根据区站号查询如果ftp未开启不执行 或者设备超时，不做处理
        String ifOutTime = GuavaCacheUtil.ifTimeOut(String.valueOf(interfaceApiBo.getDeviceId()), interfaceApiBo.getTimeInterval());
        if (!Constants.TRIGGER_OPEN_STATUE.equals(interfaceApiBo.getStatus()) || GuavaCacheUtil.getSTOPED().equals(ifOutTime)) {
            return;
        }
        String deviceStation = interfaceApiBo.getDeviceStation();
        List<JSONObject> jsonObjectList = new ArrayList<>();
        sensorsMap.get(deviceStation + "_" + cron).forEach(sensorAliasId -> {
            Optional<IotMonitorDataBo> optional = Optional.ofNullable(GuavaCacheUtil.getMonitorDataMap().get(interfaceApiBo.getDeviceId(), sensorAliasId));
            if (optional.isPresent()) {
                JSONObject target = new JSONObject();
                target.put("sensorId", sensorAliasId);
                target.put("val", optional.get().getStringValue());
                target.put("unit", optional.get().getUnit());
                if ("LC001".equals(deviceStation) || "LC002".equals(deviceStation)) {
                    String sensorAliasName = map.get(deviceStation + "_" + sensorAliasId);
                    target.put("name", Objects.isNull(sensorAliasName) ? optional.get().getSensorAliasName() : sensorAliasName);
                } else {
                    target.put("name", optional.get().getSensorAliasName());
                }
                jsonObjectList.add(target);
            }
        });
        CompletableFuture.runAsync(() -> {
            try {
                if (!jsonObjectList.isEmpty()) {
                    uploadFtp(interfaceApiBo, JSONObject.toJSONString(jsonObjectList), cron);
                }
            } catch (Exception e) {
                log.error("6#######uploadImage error", e);
            }
        });
    }

    /**
     * Upload ftp.
     *
     * @param interfaceApiBo the address
     * @param content        the content
     * @param cron           the cron
     */
    public void uploadFtp(IotInterfaceApiBo interfaceApiBo, String content, String cron) {
        FTPConfig ftpConfig = JSON.parseObject(interfaceApiBo.getInterfaceContent(), FTPConfig.class);
        //创建基于FTP协议访问文件服务器的客户端对象
        final String filePath = StringUtils.format("{}/{}", interfaceApiBo.getDeviceStation(), DateUtils.datePath());
        final String fileName = StringUtils.format("{}_{}_{}.{}", interfaceApiBo.getDeviceStation(), DateUtils.getYYYYMMDDHHMMTime(), cron, "json");
        FTPClient ftpClient = new FTPClient();
        try {
            ftpClient.connect(ftpConfig.ftphost(), ftpConfig.ftpport());
            ftpClient.login(ftpConfig.ftpuser(), ftpConfig.ftppassword());
            ftpClient.connect("124.114.99.54", 1111);
            ftpClient.login("admin", "k%!yWuQoyMbEJ6ed");
            ftpClient.enterLocalPassiveMode();
            String[] dirs = filePath.split("/");
            String currentDir = "/";
            boolean success = ftpClient.changeWorkingDirectory(currentDir + filePath);
            if (!success) {
                for (String dirName : dirs) {
                    if (!dirName.isEmpty()) {
                        currentDir += dirName + "/";
                        success = ftpClient.changeWorkingDirectory(currentDir);
                        if (!success) {
                            success = ftpClient.makeDirectory(dirName);
                            if (success) {
                                ftpClient.changeWorkingDirectory(dirName);
                            } else {
                                log.error("Failed to create directory:{} ", dirName);
                            }
                        }
                    }
                }
            }
            // 将字符串转换为字节数组
            ftpClient.setFileType(FTPClient.ASCII_FILE_TYPE);
            boolean isStore = ftpClient.storeFile(fileName, new ByteArrayInputStream(content.getBytes()));
            ftpClient.disconnect();
        } catch (Exception e) {
            log.error("传感器数据JSON文件上传ftp产生异常:", e);
        } finally {
            try {
                if (ftpClient.isConnected()) {
                    ftpClient.logout(); // 登出
                    ftpClient.disconnect(); // 断开连接
                }
            } catch (IOException e) {
                log.error("传感器数据JSON ftpClient 关闭连接产生异常:", e);
            }
        }
    }
}